/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hxg.portmgr.core.oper.snmp.task;

import hxg.portmgr.core.device.Device;
import hxg.portmgr.core.device.intf.AbstractIntf;
import hxg.portmgr.core.oper.OperType;
import hxg.portmgr.core.oper.snmp.SnmpOper;
import hxg.portmgr.core.oper.snmp.SnmpOperUtils;
import hxg.portmgr.core.oper.snmp.oidgroup.OidEntry;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.snmp4j.CommunityTarget;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.Variable;

/**
 *
 * @author hxg
 */
public class DefaultTask implements Task {

    final Device dev;
    List<AbstractIntf> intfs = new ArrayList<>();
    final String taskName;
    Method method;
    SnmpOper oper;
    TaskGetMode mode = TaskGetMode.Table;

    public DefaultTask(Device dev, String taskName) {
        this.dev = dev;
        this.taskName = taskName;
        Method[] methods = dev.getOper(OperType.SnmpOper).getClass().getMethods();
        oper = (SnmpOper) dev.getOper(OperType.SnmpOper);
        for (Method m : methods) {
            TaskSupport support = m.getAnnotation(TaskSupport.class);
            if (support != null) {
                if (taskName.equals(support.chsname())) {
                    method = m;
                    break;
                }
            }
        }

    }

    public TaskGetMode getMode() {
        return mode;
    }

    public void setMode(TaskGetMode mode) {
        if (mode != null) {
            this.mode = mode;
        }
    }

    @Override
    public List<TaskResultCell> execute() {
        List<TaskResultCell> list = new ArrayList<>();
        if (method != null) {
            try {
                OidEntry[] oidGroups = (OidEntry[]) method.invoke(oper);
                CommunityTarget target = SnmpOperUtils.getTarget(oper.getIp(), oper.getReadCommunity());
                switch (mode) {
                    case Row:
                        for (AbstractIntf inf : intfs) {
                            Map<OidEntry, Variable> mp = SnmpOperUtils.getIntfVariblesOfIntf(inf.getIndex(), oidGroups, target);
                            long date = System.currentTimeMillis();
                            for (OidEntry entry : mp.keySet()) {
                                TaskResultCell taskEntry = new TaskResultCell();
                                taskEntry.setScandate(date);
                                taskEntry.setIfidx(inf.getIndex());
                                taskEntry.setIp(oper.getIp());
                                taskEntry.setOid(entry.oidValue());
                                taskEntry.setParam(entry.getParamType());
                                taskEntry.setValue(mp.get(entry).toString());
                                list.add(taskEntry);
                            }
                        }
                        break;
                    case Table:
                        Map<OID, Map<OidEntry, Variable>> mp = SnmpOperUtils.getVariblesOfOidEntryByRow(oidGroups, target);
                        long date = System.currentTimeMillis();
                        for (OID oid : mp.keySet()) {
                            Map<OidEntry, Variable> varmp = mp.get(oid);
                            String ifidx = oid.toString();
                            for (OidEntry entry : varmp.keySet()) {
                                TaskResultCell taskEntry = new TaskResultCell();
                                taskEntry.setScandate(date);
                                taskEntry.setIfidx(ifidx);
                                taskEntry.setIp(oper.getIp());
                                taskEntry.setOid(entry.oidValue());
                                taskEntry.setParam(entry.getParamType());
                                taskEntry.setValue(varmp.get(entry).toString());
                                list.add(taskEntry);
                            }
                        }
                        break;
                }
            } catch (IOException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
                Logger.getLogger(DefaultTask.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return list;

//        try {
//            SnmpOper oper = dev.getSnmpOper();
//            return TaskManager.getResult(oper, taskName, mode, intfs);
//        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IOException ex) {
//            Logger.getLogger(DefaultTask.class.getName()).log(Level.SEVERE, null, ex);
//        }
//        return new ArrayList<>();
    }
}
